package org.HU.train.member.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import jakarta.annotation.Resource;
import org.HU.train.common.exception.BusinessException;
import org.HU.train.common.exception.BusinessExceptionEnum;
import org.HU.train.common.util.JwtUtil;
import org.HU.train.common.util.SnowUtil;
import org.HU.train.member.domain.Member;
import org.HU.train.member.domain.MemberExample;
import org.HU.train.member.mapper.MemberMapper;
import org.HU.train.member.request.member.MemberLoginReq;
import org.HU.train.member.request.member.MemberRegisterReq;
import org.HU.train.member.request.member.MemberSendCodeReq;
import org.HU.train.member.response.MemberLoginResp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Author ZUZ
 * @Description: member表相关操作，实际上功能并不完善，待增强
 * @Date 2024-12-17 17:01
 * @ClassName: MemberService
 */
@Service
public class MemberService {

    private static final Logger Log = LoggerFactory.getLogger(MemberService.class);

    @Resource
    private MemberMapper memberMapper;

    /**
     * 查找用户总数目接口
     * 实际上这个接口没用，用户无权限查找总数
     */
    public Integer count(){
        return Math.toIntExact(memberMapper.countByExample(null));
    }

    /**
     * 用户注册接口，若手机号码已存在，返回错误信息
     * 若不存在。向数据库member插入用户手机号，并用雪花算法生成主键ID
     * 雪花算法已封装为一个工具类放在common模块中
     */
    public long register(MemberRegisterReq req){
        String mobile=req.getMobile();

        //判断该手机号是否已存在
        Member memberDB = getMembersByMobile(mobile);

        if(ObjectUtil.isNotNull(memberDB)){
            //return members.get(0).getId();
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_EXIST);
        }

        Member member = new Member();
        //这是hutool集成的雪花算法
        member.setId(SnowUtil.getSnowflakeNextId());
        member.setMobile(mobile);
        memberMapper.insert(member);
        return member.getId();
    }

    /**
     * 发送验证码的接口，若手机号不存在则向数据库member中插入用户手机号，并用雪花算法生成主键ID
     * 实现有问题，应该验证码验证通过以后再插入数据，否则提示验证码错误以及注册失败等信息
     */
    public void sendCode(MemberSendCodeReq req){
        String mobile=req.getMobile();

        //判断该手机号是否已存在
        Member memberDB = getMembersByMobile(mobile);

        //如果手机号不存在，则插入记录
        if(ObjectUtil.isNull(memberDB)){
            Log.info("手机号不存在，插入一条记录");
            Member member = new Member();
            //这是hutool集成的雪花算法
            member.setId(SnowUtil.getSnowflakeNextId());
            member.setMobile(mobile);
            memberMapper.insert(member);
        }else {
            Log.info("手机号存在，不插入记录");
        }

        //生成短信验证码
        //String code = RandomUtil.randomString(4);
        String code = "8888";
        Log.info("生成短信验证码:{}",code);

        //保存短信记录表：手机号，短信验证码，有效期，是否已使用，业务类型(注册，忘记密码),发送时间，使用时间

        //对接短信通道，发送短信
    }

    /**
     * 登录接口，判断手机号和短信验证码是否正确
     * 若手机号不存在，则提示用户先获取短信验证码完成注册
     * 若短信验证码失败，提示用户
     * 若成功，使用common中封装的JWT工具类生成JWT，一并返回给前端
     */
    public MemberLoginResp login(MemberLoginReq req){
        String mobile=req.getMobile();
        String code = req.getCode();
        Member memberDB = getMembersByMobile(mobile);

        //如果手机号不存在，则提示用户先获取短信验证码完成注册
        if(ObjectUtil.isNull(memberDB)){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_NOT_EXIST);
        }

        //校验短信验证码
        if(!"8888".equals(code)){
            throw new BusinessException(BusinessExceptionEnum.MEMBER_MOBILE_CODE_ERROR);
        }

        MemberLoginResp memberLoginResp = BeanUtil.copyProperties(memberDB, MemberLoginResp.class);
        String token = JwtUtil.createToken(memberLoginResp.getId(), memberLoginResp.getMobile());
        memberLoginResp.setToken(token);

        return memberLoginResp;


    }

    private Member getMembersByMobile(String mobile) {
        MemberExample memberExample = new MemberExample();
        memberExample.createCriteria().andMobileEqualTo(mobile);
        List<Member> members = memberMapper.selectByExample(memberExample);
        if(CollUtil.isEmpty(members)){
            return null;
        }else {
            return members.get(0);
        }
    }
}
